home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 4
/
FM Towns Free Software Collection 4 - Disc 1.iso
/
t_os
/
comma000
/
comma000.asm
next >
Wrap
Assembly Source File
|
1991-10-18
|
7KB
|
342 lines
;COMMA000.ASM テンキーの「000」を「,」に変換する
page 58,132
.8086
comment *
COMMA000.COM (C)1991. Boko.
テンキー部の「000」キーを「,」(カンマ)に変更する。
常駐してINT 90(キーボードBIOS)をフックし、
キーの読み取り時にコードをすりかえる
1991.05.19 V1.0 初版(Nifty-Serve FTOWNS1 DL3 にアップロード)
1991.06.09 常駐サイズの縮小
1991.08.11 V1.1 フリコレ4用(^^;)にコメントを追加
*
TAB EQU 009H ;タブコード
CR EQU 00DH ;キャリッジリターンコード
LF EQU 00AH ;ラインフィードコード
EOS EQU '$' ;End Of String 文字列の終端(DOS call用)
CODE SEGMENT ;COM形式
ASSUME CS:CODE
ASSUME DS:CODE
ASSUME ES:CODE
org 002CH
ENV_SEG DW ? ;環境変数のセグメント(DOSが設定する)
org 0070H
; データ部
; (PSP内のFCB領域をワークエリアとして利用している)
KEY_INT_VEC label dword ;INT 90ベクトルの保存領域
KEY_INT_OFF DW ?
KEY_INT_SEG DW ?
SAVE_AX DW ? ;キー待ちあり?なし?の保存領域
org 0080h
COMMAND_PARAM DB 80h dup(?) ;コマンドラインからのパラメータ
;(1文字目はパラメータの長さ)
; コード部
;
org 0100h
START:
JMP short INITIALIZE ;初期化ルーチンへジャンプ
; 常駐部
; ~~~~~~
ENTRY_INT90H proc far
;アプリケーションソフトが
;INT 90を実行するとまず
;ここに制御が移る
;INT 90 「文字の読込」のインタフェィス
;CALL WITH
; AH=09H
; AL=0 :キー入力待ち
; AL=1 :キー入力待ちなし
;RETURNS
; AH=0 :正常終了
; DH=0FFH :入力文字なし
; DH!=0FFH:入力文字あり
; DL: 文字コード/スキャンコード
; BH: キーアドレス
; BL: シフトキー状態
CMP AH,009H ; 「文字の読込」の機能?
JE ZERO_TO_COMMA
JMP CS:KEY_INT_VEC ;それ以外は本当のINT 90hに制御を渡す
ENTRY_INT90H endp
ZERO_TO_COMMA proc far
;この部分が実行されるときには
;ES,DS,SSが何を指しているかは
;不定であることに注意。データ
;部をアクセスするためにCS:で
;セグメントオーバーライトする
;必要がある
STI ;割り込み許可
MOV CS:SAVE_AX,AX ;呼び出し機能をセーブしておく
;ここで本来のINT 90を呼ぶのだ
;が実際にINT 90Hを実行すると
;無限ループになるのでCALLで呼
;び出す。次のpushf~callで
;INT 90と同じになる。
PUSHF
CLI
CALL CS:KEY_INT_VEC ;本当のINT 90h FUNC 9を呼ぶ
;「000」キー以外は呼び出しもとの
;アプリケーションに戻る
;キー待ちなしが指定されていて
;キー入力がないときも戻る
CMP BH,04AH ;「000」キーのキーアドレス?
JNE RETURN_TO_APL
;「000」キーの場合は一つ目と二つ目
;の「0」は読み捨てる
MOV AX,CS:SAVE_AX
PUSHF
CLI
CALL CS:KEY_INT_VEC ;本当のINT 90h FUNC 9をコール
CMP BH,04AH ;「000」キーのキーアドレス?
JNE RETURN_TO_APL
;「000」キーの場合三つ目の「0」を「,」
;に変えてもとのアプリに戻る
MOV AX,CS:SAVE_AX
PUSHF
CLI
CALL CS:KEY_INT_VEC ;本当のINT 90h FUNC 9をコール
CMP BH,04AH ;「000」キーのキーアドレス?
JNE RETURN_TO_APL
MOV DL,',' ;CAMMAにすりかえる
RETURN_TO_APL:
;呼び出しもとのアプリケーション
;にもどる。
;INTからの戻りなのでふつうの
;RET命令は使えないことに注意
IRET
ZERO_TO_COMMA endp
; 初期化部
; ~~~~~~~~
;初期化部はプログラムが起動
;したときに一度だけ実行される
;常駐終了するときに初期化部は
;開放される
INITIALIZE proc
;コマンドラインのパラメータを
;チェックします。
CLD
MOV SI,offset COMMAND_PARAM+1
SKIP_BLANK:
LODSB
CMP AL,' ' ;空白は無視
JE SKIP_BLANK
CMP AL,TAB ;タブコードは無視
JE SKIP_BLANK
CMP AL,CR ;パラメータは全く無かった
JE NO_PARAM
;「S」とか「R」とかの直前の文字は
;「/」でも「-」でもよい
;はっきりいってなんでも良い
;(手抜き)
;またこれ以降の文字もまったく
;チェックしていない。したがって
;comma000 /s /r
;のように書くと最初のパラメータ
;のみが有効になる。
LODSB
CMP AL,'S'
JE START_STAY ;S Stay 常駐開始
CMP AL,'s'
JE START_STAY
CMP AL,'R' ;R Remove 常駐終了
JE END_STAY
CMP AL,'r'
JE END_STAY
NO_PARAM:
;パラメターなし
CALL STAY_CHK
JE END_STAY
; JMP START_STAY ;次に流れ込む
INITIALIZE endp
START_STAY PROC
; 常駐開始
CALL STAY_CHK
PUSH CS
POP ES ;ES←CS
JE ALREADY_STAY
;常駐しているかどうかの判断の
;鍵になる文字列を転送する
;PSP内を使うのはVMAPなどの
;メモリ利用状況表示ツールで
;PSPを見るものが多いから
MOV DI,offset COMMAND_PARAM
MOV SI,offset ID_MSG
MOV CX,27
REPNZ MOVSB
;INT 90のベクトルを取得する
MOV AX,03590H ;割り込みベクトルの取得
INT 021H ;DOSシステムコール
;INT 90のベルトルを保存する
;ES:BX 割込みベクトルのアドレス
MOV KEY_INT_OFF,BX
MOV KEY_INT_SEG,ES
;新しい割り込みベクトルの設定
;COMMA000の入口を設定する
MOV DX,offset ENTRY_INT90H
MOV AX,02590H ;割り込みベクトルの設定
INT 021H ;DOSシステムコール
;常駐開始メッセージを出力
;MS-DOSのシステムコールで文字を
;出力する場合キーのチェックが
;行われる
;すでにINT 90は書換え済なので
;常駐部が呼ばれることになる
;もしもメッセージが正常に出力
;されない時は、常駐部が変なの
;かもしれません。
MOV DX,offset STR_MSG
CALL PUTS
MOV ES,ENV_SEG ;環境変数エリアの
MOV AH,049H ;メモリブロックの開放
INT 021H ;DOSシステムコール
XOR AX,AX ;AX←0
MOV ENV_SEG,AX ;cf. ◎h!FM 1990-12-p148.
;常駐するメモリサイズの計算は
;パラグラフ単位なので計算が
;ちょっとめんどう
;PSPの分を忘れてはいけない
MOV DX,(INITIALIZE+15-START)/10H+10H
MOV AX,03100H ;常駐終了
INT 021H ;DOSシステムコール
START_STAY endp
NO_OPERATION proc
CANT_REMOVE: MOV DX,offset EN2_MSG
JMP short PUT_END
ALREADY_STAY:
MOV DX,offset ST2_MSG
PUT_END:
CALL PUTS
MOV AX,04C00H ;プロセスの終了(リタンコード0)
INT 021H ;DOSシステムコール
NO_OPERATION endp
END_STAY proc
CALL STAY_CHK
JNE CANT_REMOVE
;INT90ベクタをもとに戻す
LDS DX,ES:KEY_INT_VEC
MOV AX,02590H ;割り込みベクタの設定
INT 21H ;DOSシステムコール
;常駐していたメモリブロック開放
MOV AH,049H ;メモリブロック(ES)の開放
INT 21H ;DOSシステムコール
;常駐終了メッセージの出力
PUSH CS
POP DS
MOV DX,offset END_MSG
JMP PUT_END
END_STAY endp
STAY_CHK PROC
;すでにCOMMA000が常駐しているかどうかのチェック
;RETURN
; Z :COMMA000が常駐している
; NZ:COMMA000はみつからなかった
;「COMMA000」の文字列がINT 90のセグメントにあるかどうかを
;調べている。まぁこの程度のチェックで十分でしょう。
;本当は別のソフトがINT 90をフックしてるかもしれないのだが
;その場合は開放することもできなくなるのでチェックはしない。
;このルーチンからリターンした後はESの値が変わることに注意
MOV AX,03590H ;割り込みベクトルの取得(ES:BX)
INT 021H ;DOSシステムコール
MOV DI,offset COMMAND_PARAM
MOV SI,offset ID_MSG
MOV CX,ID_LEN
REPZ CMPSB
RET
STAY_CHK ENDP
; メッセージ出力
; (DX:メッセージ開始アドレス)
;MS-DOSのシステムコールによる
;文字列な出力なので
;Townsシステムソフトウェアで実行する場合は
;出力は見えない
PUTS proc
MOV AH,09H ;文字列の出力
INT 021H ;DOSシステムコール
RET
PUTS endp
ID_MSG DB 24
DB 'Comma000 (C)1991. Boko.',CR,0
STR_MSG DB 'Comma000 V1.1 for FM TOWNS & FMR Series'
DB ' (C)1991. Boko.',CR,LF
DB 'テンキーの「000」を「,」に変更します。',CR,LF
DB EOS
END_MSG DB 'テンキーの「000」はもとどおりの「000」です。',CR
DB EOS
ST2_MSG DB 'Comma000はすでに常駐しています',CR
DB EOS
EN2_MSG DB 'Comma000はありません',CR
DB EOS
ID_LEN = STR_MSG - ID_MSG
CODE ENDS
END START